package com.lianyi.push.share.tcpclient;

import android.content.Context;

import com.lianyi.push.entity.TcpMessageEvent;
import com.lianyi.push.entity.TcpMsgBean;
import com.lianyi.push.share.ConstantValue;
import com.lianyi.push.share.NettyConfig;
import com.lianyi.push.share.listener.TcpSeiviceToClientMessageListener;
import com.lianyi.push.util.CommonUtils;
import com.lianyi.push.util.LogUtil;

import org.simple.eventbus.EventBus;

import java.net.InetSocketAddress;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;

/**
 * Created by leilei on 2018/8/15.
 */

public class TcpClientHandler extends ChannelInboundHandlerAdapter {
    private Context mContext;
    //    private int count;
    private TcpSeiviceToClientMessageListener tcpSeiviceToClientMessageListener;
    private ScheduledExecutorService mScheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
    private ScheduledExecutorService mScheduledExecutorService2 = Executors.newSingleThreadScheduledExecutor();

    public TcpClientHandler(Context mContext, TcpSeiviceToClientMessageListener listener) {
        this.mContext = mContext;
        this.tcpSeiviceToClientMessageListener = listener;
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        System.out.println("TcpClientHandler循环触发时间：" + new Date());
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.WRITER_IDLE) {
                ctx.channel().writeAndFlush("biubiu");
            }
        }
        ctx.close();
    }

    // 客户端与服务端，连接成功回调
    @Override
    public void channelActive(final ChannelHandlerContext ctx) throws Exception {
//        count = 0;
        System.out.println("客户端开启" + ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostName());
        TcpClient.hashMap.put(((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostName(), "true");
        if (!NettyConfig.client_group.contains(ctx.channel())) {
            NettyConfig.client_group.add(ctx.channel());
        }
//        mScheduledExecutorService.scheduleAtFixedRate(new Runnable() {
//            @Override
//            public void run() {
//                String data = ConstantValue.HEAD_HEART_BEAT;
//                // 获得要发送信息的字节数组
//                byte[] content = data.getBytes();
//                // 要发送信息的长度
//                int contentLength = content.length;
//
//                SmartCarProtocol protocol = new SmartCarProtocol(contentLength, content);
//                ctx.writeAndFlush(protocol);
//            }
//        }, 1000, 3000, TimeUnit.MILLISECONDS);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        String hostname = ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostName();
        System.out.println("客户端关闭:" + hostname);
        TcpClient.hashMap.put(hostname, "false");
        if (NettyConfig.client_group.contains(ctx.channel())) {
            NettyConfig.client_group.remove(ctx.channel());
        }
        shutdown();
        channelInactives(ctx, hostname);
    }

    // 只是读数据，没有写数据的话
    // 需要自己手动的释放的消息
    //客户端接收到服务器的消息
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        try {
            // 用于获取客户端发来的数据信息
            TcpMsgBean tcpMsgBean = (TcpMsgBean) msg;
            System.out.println("Client接受服务端的信息 :" + tcpMsgBean.toString());
            if (tcpSeiviceToClientMessageListener != null) {
                tcpSeiviceToClientMessageListener.tcpSeiviceToClientMessage(ctx, msg);
            }
            EventBus.getDefault().post(new TcpMessageEvent(tcpMsgBean.getType(), tcpMsgBean.getBody(), tcpMsgBean.getLength()), ConstantValue.TCP_SERVICE_MESSAGE);
//            if (!ConstantValue.HEAD_HEART_BEAT.equals(new String(body.getContent()) + "")) {
//                EventBus.getDefault().post(new FristTextEvent(new String(body.getContent()) + ctx.channel().remoteAddress(), ConstantValue.CLIENT_MESSAGE, 0));
//                LogUtil.e("Client接受服务端的信息", new String(body.getContent()) + "==");
//            }
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    public synchronized void channelInactives(final ChannelHandlerContext ctx, final String hostname) {
        TcpClient.hashMapCount.put(hostname, 0);
        mScheduledExecutorService2.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
//                connectService(ctx, hostname);
            }
        }, 2000, 4000, TimeUnit.MILLISECONDS);
    }

    public synchronized void connectService(ChannelHandlerContext ctx, String hostname) {
        int count = TcpClient.hashMapCount.get(hostname);
        if (count < ConstantValue.TCP_CONNECT_COUNT && TcpClient.hashMap.get(hostname).equals("false")) {
            if (CommonUtils.Available(mContext)) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count++;
                TcpClient.hashMapCount.put(hostname, count);
                System.out.println("TcpClientHandler客户端重新连接第 :" + count + "次:" + hostname);
                TcpClient.getInstance().reconnection(hostname);
                if (TcpClient.getInstance().isConnect(hostname)) {
                    TcpClient.hashMapCount.put(hostname, 0);
                    LogUtil.e("TcpClientHandler已经连接客户端成功" + count + "次", "已经连接客户端成功" + count + "次");
                    shutdown2();
                } else {
                    LogUtil.e("TcpClientHandler连接客户端失败" + count + "次", "连接客户端失败" + count + "次");
                }
            } else {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                LogUtil.e("TcpClientHandler无网络无网络无网络", "无网络无网络无网络");
            }
        } else {
            shutdown();
            shutdown2();
        }
    }

    private void shutdown() {
        if (mScheduledExecutorService != null) {
            mScheduledExecutorService.shutdown();
            mScheduledExecutorService = null;
        }
    }

    private void shutdown2() {
        if (mScheduledExecutorService2 != null) {
            mScheduledExecutorService2.shutdown();
            mScheduledExecutorService2 = null;
        }
    }
}
